<!DOCTYPE html>
<!-- saved from url=(0053)http://www.zhufengpeixun.cn/2020/html/82.1.react.html -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>珠峰架构师成长计划</title>
    <link rel="stylesheet" type="text/css" href="./react基础_files/main.css">
</head>
<body>
<div class="nav" style="height: 81px;">
    <div class="logo">
        
            珠峰架构师成长计划
        
    </div>
<ul><li><a href="http://www.zhufengpeixun.cn/2020/index.html">0.Async</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/0.editor.html">0.editor</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/0.module.html">0.module</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/1.ES2015.html">1.ES2015</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/2.Promise.html">2.Promise</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/3.Node.html">3.Node</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/4.NodeInstall.html">4.NodeInstall</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/5.REPL.html">5.REPL</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/6.NodeCore.html">6.NodeCore</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/7.module&amp;NPM.html">7.module&amp;NPM</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/8.Encoding.html">8.Encoding</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/9.Buffer.html">9.Buffer</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/10.fs.html">10.fs</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/11.Stream-1.html">11.Stream-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/11.Stream-2.html">11.Stream-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/11.Stream-3.html">11.Stream-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/11.Stream-4.html">11.Stream-4</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/12-Network-2.html">12-Network-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/12.NetWork-3.html">12.NetWork-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/12.Network-1.html">12.Network-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/13.tcp.html">13.tcp</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/14.http-1.html">14.http-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/14.http-2.html">14.http-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/15.compress.html">15.compress</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/16.crypto.html">16.crypto</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/17.process.html">17.process</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/18.yargs.html">18.yargs</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/19.cache.html">19.cache</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/20.action.html">20.action</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/21.https.html">21.https</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/22.cookie.html">22.cookie</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/23.session.html">23.session</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/24.express-1.html">24.express-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/24.express-2.html">24.express-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/24.express-3.html">24.express-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/24.express-4.html">24.express-4</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/25.koa-1.html">25.koa-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-1-basic.html">26.webpack-1-basic</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-2-optimize.html">26.webpack-2-optimize</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-3-file.html">26.webpack-3-file</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-4.tapable.html">26.webpack-4.tapable</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-5-AST.html">26.webpack-5-AST</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-6-sources.html">26.webpack-6-sources</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-7-loader.html">26.webpack-7-loader</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-8-plugin.html">26.webpack-8-plugin</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-9-hand.html">26.webpack-9-hand</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/26.webpack-10-prepare.html">26.webpack-10-prepare</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/28.redux.html">28.redux</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/28.redux-jwt-back.html">28.redux-jwt-back</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/28.redux-jwt-front.html">28.redux-jwt-front</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-1.html">29.mongodb-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-2.html">29.mongodb-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-3.html">29.mongodb-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-4.html">29.mongodb-4</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-5.html">29.mongodb-5</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/29.mongodb-6.html">29.mongodb-6</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-1-mysql.html">30.cms-1-mysql</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-2-mysql.html">30.cms-2-mysql</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-3-mysql.html">30.cms-3-mysql</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-4-nunjucks.html">30.cms-4-nunjucks</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-5-mock.html">30.cms-5-mock</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-6-egg.html">30.cms-6-egg</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-7-api.html">30.cms-7-api</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-8-roadhog.html">30.cms-8-roadhog</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-9-yaml.html">30.cms-9-yaml</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-10-umi.html">30.cms-10-umi</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-12-dva.html">30.cms-12-dva</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-13-dva-ant.html">30.cms-13-dva-ant</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-14-front.html">30.cms-14-front</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/30.cms-15-deploy.html">30.cms-15-deploy</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/31.dva.html">31.dva</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/31.cms-13-dva-antdesign.html">31.cms-13-dva-antdesign</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/33.redis.html">33.redis</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/34.unittest.html">34.unittest</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/35.jwt.html">35.jwt</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/36.websocket-1.html">36.websocket-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/36.websocket-2.html">36.websocket-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat-api-1.html">38.chat-api-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat-api-2.html">38.chat-api-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat-3.html">38.chat-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat-api-3.html">38.chat-api-3</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat.html">38.chat</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat2.html">38.chat2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/38.chat2.html">38.chat2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/39.crawl-0.html">39.crawl-0</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/39.crawl-1.html">39.crawl-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/39.crawl-2.html">39.crawl-2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/40.deploy.html">40.deploy</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/41.safe.html">41.safe</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/42.test.html">42.test</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/43.nginx.html">43.nginx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/44.enzyme.html">44.enzyme</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/45.docker.html">45.docker</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/46.elastic.html">46.elastic</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/47.oauth.html">47.oauth</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/48.wxpay.html">48.wxpay</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/index.html">index</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/51.typescript.html">51.typescript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/52.UML.html">52.UML</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/53.design.html">53.design</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/index.html">index</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/54.linux.html">54.linux</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/57.ts.html">57.ts</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/56.react-ssr.html">56.react-ssr</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/58.ts_react.html">58.ts_react</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/59.ketang.html">59.ketang</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/59.ketang2.html">59.ketang2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.1.devops-linux.html">61.1.devops-linux</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.2.devops-vi.html">61.2.devops-vi</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.3.devops-user.html">61.3.devops-user</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.4.devops-auth.html">61.4.devops-auth</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.5.devops-shell.html">61.5.devops-shell</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.6.devops-install.html">61.6.devops-install</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.7.devops-system.html">61.7.devops-system</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.8.devops-service.html">61.8.devops-service</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.9.devops-network.html">61.9.devops-network</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.10.devops-nginx.html">61.10.devops-nginx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.11.devops-docker.html">61.11.devops-docker</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.12.devops-jekins.html">61.12.devops-jekins</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.13.devops-groovy.html">61.13.devops-groovy</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.14.devops-php.html">61.14.devops-php</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.15.devops-java.html">61.15.devops-java</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.16.devops-node.html">61.16.devops-node</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/61.17.devops-k8s.html">61.17.devops-k8s</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.1.react-basic.html">62.1.react-basic</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.2.react-state.html">62.2.react-state</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.3.react-high.html">62.3.react-high</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.4.react-optimize.html">62.4.react-optimize</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.5.react-hooks.html">62.5.react-hooks</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.6.react-immutable.html">62.6.react-immutable</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.7.react-mobx.html">62.7.react-mobx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/62.8.react-source.html">62.8.react-source</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/63.1.redux.html">63.1.redux</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/63.2.redux-middleware.html">63.2.redux-middleware</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/63.3.redux-hooks.html">63.3.redux-hooks</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/63.4.redux-saga.html">63.4.redux-saga</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/63.5.redux-saga-hand.html">63.5.redux-saga-hand</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/64.1.router.html">64.1.router</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/64.2.router-connected.html">64.2.router-connected</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/65.1.typescript.html">65.1.typescript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/65.2.typescript.html">65.2.typescript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/65.3.typescript.html">65.3.typescript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/65.4.antd.html">65.4.antd</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/65.4.definition.html">65.4.definition</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-1.vue-base.html">66-1.vue-base</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-2.vue-component.html">66-2.vue-component</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-3.vue-cli3.0.html">66-3.vue-cli3.0</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-4.$message%E7%BB%84%E4%BB%B6.html">66-4.$message组件</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-5.Form%E7%BB%84%E4%BB%B6.html">66-5.Form组件</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-6.tree.html">66-6.tree</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-7.vue-router-apply.html">66-7.vue-router-apply</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-8.axios-apply.html">66-8.axios-apply</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-9.vuex-apply.html">66-9.vuex-apply</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-10.jwt-vue.html">66-10.jwt-vue</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-11.vue-ssr.html">66-11.vue-ssr</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-12.nuxt-apply.html">66-12.nuxt-apply</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-13.pwa.html">66-13.pwa</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-14.vue%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95.html">66-14.vue单元测试</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/66-15.%E6%9D%83%E9%99%90%E6%A0%A1%E9%AA%8C.html">66-15.权限校验</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/67-1-network.html">67-1-network</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/68-2-wireshark.html">68-2-wireshark</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/7.npm2.html">7.npm2</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/69-hooks.html">69-hooks</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/70-deploy.html">70-deploy</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/71-hmr.html">71-hmr</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/72.deploy.html">72.deploy</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/73.import.html">73.import</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/74.mobile.html">74.mobile</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/75.webpack-1.%E6%96%87%E4%BB%B6%E5%88%86%E6%9E%90.html">75.webpack-1.文件分析</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/75.webpack-2.loader.html">75.webpack-2.loader</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/75.webpack-3.%E6%BA%90%E7%A0%81%E6%B5%81%E7%A8%8B.html">75.webpack-3.源码流程</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/75.webpack-4.tapable.html">75.webpack-4.tapable</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/75.webpack-6.%E5%AE%9E%E7%8E%B0.html">75.webpack-6.实现</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/76.react_optimize.html">76.react_optimize</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/77.ts_ketang_back.html">77.ts_ketang_back</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/77.ts_ketang_front.html">77.ts_ketang_front</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/78.vue-domdiff.html">78.vue-domdiff</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/79.grammar.html">79.grammar</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/80.tree.html">80.tree</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/81.axios.html">81.axios</a></li><li class="active"><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html">82.1.react</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.2.react-high.html">82.2.react-high</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.3.react-router.html">82.3.react-router</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.4.redux.html">82.4.redux</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.5.redux_middleware.html">82.5.redux_middleware</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.6.connected.html">82.6.connected</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.7.saga.html">82.7.saga</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.8.dva.html">82.8.dva</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.8.dva-source.html">82.8.dva-source</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.9.roadhog.html">82.9.roadhog</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.10.umi.html">82.10.umi</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.11.antdesign.html">82.11.antdesign</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.12.ketang-front.html">82.12.ketang-front</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.12.ketang-back.html">82.12.ketang-back</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/83.upload.html">83.upload</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/84.graphql.html">84.graphql</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/85.antpro.html">85.antpro</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/86.1.uml.html">86.1.uml</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/86.2.design.html">86.2.design</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/87.postcss.html">87.postcss</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/88.react16-1.html">88.react16-1</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/89.nextjs.html">89.nextjs</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/90.react-test.html">90.react-test</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/91.react-ts.html">91.react-ts</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/92.rbac.html">92.rbac</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/93.tsnode.html">93.tsnode</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.1.JavaScript.html">94.1.JavaScript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.2.JavaScript.html">94.2.JavaScript</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.3.MODULE.html">94.3.MODULE</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.4.EventLoop.html">94.4.EventLoop</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.5.%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0.html">94.5.文件上传</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.6.https.html">94.6.https</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/94.7.%20nginx.html">94.7. nginx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/95.1.%20react.html">95.1. react</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/95.2.react.html">95.2.react</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/96.1.react16.html">96.1.react16</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/96.2.fiber.html">96.2.fiber</a></li></ul></div>


<div class="warpper">

    <div class="page-toc">
        <ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t01.%20%E4%BB%80%E4%B9%88%E6%98%AFReact?">1. 什么是React?</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t12.%20%E7%BB%84%E4%BB%B6%E5%8C%96%E7%9A%84%E6%A6%82%E5%BF%B5">2. 组件化的概念</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t23.%E6%90%AD%E5%BB%BAReact%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83">3.搭建React开发环境</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t34.JSX">4.JSX</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t44.1%20%E4%BB%80%E4%B9%88%E6%98%AFJSX">4.1 什么是JSX</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t54.2%20%E4%BB%80%E4%B9%88%E6%98%AF%E5%85%83%E7%B4%A0">4.2 什么是元素</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t64.3%20JSX%E8%A1%A8%E8%BE%BE%E5%BC%8F">4.3 JSX表达式</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t74.4%20JSX%E5%B1%9E%E6%80%A7">4.4 JSX属性</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t84.5%20JSX%E4%B9%9F%E6%98%AF%E5%AF%B9%E8%B1%A1">4.5 JSX也是对象</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t94.6%20%E6%9B%B4%E6%96%B0%E5%85%83%E7%B4%A0%E6%B8%B2%E6%9F%93">4.6 更新元素渲染</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t104.7%20React%E5%8F%AA%E4%BC%9A%E6%9B%B4%E6%96%B0%E5%BF%85%E8%A6%81%E7%9A%84%E9%83%A8%E5%88%86">4.7 React只会更新必要的部分</a></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t115.%20%E7%BB%84%E4%BB%B6%20&amp;%20Props">5. 组件 &amp; Props</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t125.1%20%E5%87%BD%E6%95%B0(%E5%AE%9A%E4%B9%89%E7%9A%84)%E7%BB%84%E4%BB%B6">5.1 函数(定义的)组件</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t135.2%20%E7%B1%BB(%E5%AE%9A%E4%B9%89%E7%9A%84)%E7%BB%84%E4%BB%B6">5.2 类(定义的)组件</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t145.3%20%E7%BB%84%E4%BB%B6%E6%B8%B2%E6%9F%93">5.3 组件渲染</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t155.4%20%E5%A4%8D%E5%90%88%E7%BB%84%E4%BB%B6%20&amp;%20%E6%8F%90%E5%8F%96%E7%BB%84%E4%BB%B6">5.4 复合组件 &amp; 提取组件</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t165.5%20Props%E7%9A%84%E5%8F%AA%E8%AF%BB%E6%80%A7">5.5 Props的只读性</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t175.6%20%20%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5">5.6  类型检查</a></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t186.%20%E8%99%9A%E6%8B%9FDOM">6. 虚拟DOM</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t196.1%20src\index.tsx">6.1 src\index.tsx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t206.2%20src\react.tsx">6.2 src\react.tsx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t216.3%20src\typings.tsx">6.3 src\typings.tsx</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t226.4%20src\react-dom.tsx">6.4 src\react-dom.tsx</a></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t236.%20%E7%8A%B6%E6%80%81">6. 状态</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t246.1%20%E4%B8%8D%E8%A6%81%E7%9B%B4%E6%8E%A5%E4%BF%AE%E6%94%B9%20State">6.1 不要直接修改 State</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t256.2%20State%20%E7%9A%84%E6%9B%B4%E6%96%B0%E5%8F%AF%E8%83%BD%E6%98%AF%E5%BC%82%E6%AD%A5%E7%9A%84">6.2 State 的更新可能是异步的</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t266.3%20State%20%E7%9A%84%E6%9B%B4%E6%96%B0%E4%BC%9A%E8%A2%AB%E5%90%88%E5%B9%B6">6.3 State 的更新会被合并</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t276.4%20%E6%95%B0%E6%8D%AE%E6%98%AF%E5%90%91%E4%B8%8B%E6%B5%81%E5%8A%A8%E7%9A%84">6.4 数据是向下流动的</a></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t287.%20%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86">7. 事件处理</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t297.2%20this">7.2 this</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t307.3%20%E5%90%91%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%E7%A8%8B%E5%BA%8F%E4%BC%A0%E9%80%92%E5%8F%82%E6%95%B0">7.3 向事件处理程序传递参数</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t317.4%20Ref">7.4 Ref</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t327.4.1%20ref%E7%9A%84%E5%80%BC%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2">7.4.1 ref的值是一个字符串</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t337.4.2%20ref%E7%9A%84%E5%80%BC%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0">7.4.2 ref的值是一个函数</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t347.4.3%20%E4%B8%BA%20DOM%20%E5%85%83%E7%B4%A0%E6%B7%BB%E5%8A%A0%20ref">7.4.3 为 DOM 元素添加 ref</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t357.4.4%20%E4%B8%BA%20class%20%E7%BB%84%E4%BB%B6%E6%B7%BB%E5%8A%A0%20Ref">7.4.4 为 class 组件添加 Ref</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t367.4.5%20Ref%E8%BD%AC%E5%8F%91">7.4.5 Ref转发</a></li></ul></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t378.%E5%AE%9E%E7%8E%B0">8.实现</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t388.1%20src\index.js">8.1 src\index.js</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t398.2%20react\index.js">8.2 react\index.js</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t408.3%20react-dom\index.js">8.3 react-dom\index.js</a></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t418.%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F">8.生命周期</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t428.1%20%E6%97%A7%E7%89%88%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F">8.1 旧版生命周期</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t438.2%20%E6%96%B0%E7%89%88%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F">8.2 新版生命周期</a><ul><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t448.2.1%20getDerivedStateFromProps">8.2.1 getDerivedStateFromProps</a></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t458.2.2%20getSnapshotBeforeUpdate">8.2.2 getSnapshotBeforeUpdate</a></li></ul></li></ul></li><li><a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t46%E5%8F%82%E8%80%83">参考</a></li></ul>
    </div>
    
    <div class="content markdown-body">
        <h2 id="t01. 什么是React?">1. 什么是React? <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t01.%20%E4%BB%80%E4%B9%88%E6%98%AFReact?"> # </a></h2>
<ul>
<li>React 是一个用于构建用户界面的JavaScript库 核心专注于视图,目的实现组件化开发</li>
</ul>
<h2 id="t12. 组件化的概念">2. 组件化的概念 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t12.%20%E7%BB%84%E4%BB%B6%E5%8C%96%E7%9A%84%E6%A6%82%E5%BF%B5"> # </a></h2>
<ul>
<li>我们可以很直观的将一个复杂的页面分割成若干个独立组件,每个组件包含自己的逻辑和样式 再将这些独立组件组合完成一个复杂的页面。 这样既减少了逻辑复杂度，又实现了代码的重用<ul>
<li>可组合：一个组件可以和其他的组件一起使用或者可以直接嵌套在另一个组件内部</li>
<li>可重用：每个组件都是具有独立功能的，它可以被使用在多个场景中</li>
<li>可维护：每个小的组件仅仅包含自身的逻辑，更容易被理解和维护</li>
</ul>
</li>
</ul>
<h2 id="t23.搭建React开发环境">3.搭建React开发环境 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t23.%E6%90%AD%E5%BB%BAReact%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83"> # </a></h2>
<pre><code class="lang-js">cnpm i create-react-app -g
create-react-app zhufeng2019react --typescript
cd zhufeng2019react
npm start
</code></pre>
<table>
<thead>
<tr>
<th style="text-align:left">包名</th>
<th style="text-align:left">用途</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/react">react</a></td>
<td style="text-align:left">React is a JavaScript library for creating user interfaces</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/@types/react">@types/react</a></td>
<td style="text-align:left">This package contains type definitions for React (<a href="https://facebook.github.io/react/">http://facebook.github.io/react/</a>)</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/react-dom">react-dom</a></td>
<td style="text-align:left">This package serves as the entry point to the DOM and server renderers for React. It is intended to be paired with the generic React package, which is shipped as react to npm</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/@types/react-dom">@types/react-dom</a></td>
<td style="text-align:left">This package contains type definitions for React (react-dom) (<a href="https://facebook.github.io/react/">http://facebook.github.io/react/</a>)</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/react-scripts">react-scripts</a></td>
<td style="text-align:left">This package includes scripts and configuration used by Create React App</td>
</tr>
<tr>
<td style="text-align:left">typescript</td>
<td style="text-align:left">TypeScript is a language for application-scale JavaScript</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/@types/jest">@types/jest</a></td>
<td style="text-align:left">This package contains type definitions for Jest (<a href="https://jestjs.io/">https://jestjs.io/</a>)</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.npmjs.com/package/@types/node">@types/node</a></td>
<td style="text-align:left">This package contains type definitions for Node.js (<a href="https://nodejs.org/">http://nodejs.org/</a>)</td>
</tr>
</tbody>
</table>
<h2 id="t34.JSX">4.JSX <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t34.JSX"> # </a></h2>
<h3 id="t44.1 什么是JSX">4.1 什么是JSX <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t44.1%20%E4%BB%80%E4%B9%88%E6%98%AFJSX"> # </a></h3>
<ul>
<li>是一种JS和HTML混合的语法,将组件的结构、数据甚至样式都聚合在一起定义组件</li>
</ul>
<pre><code class="lang-js">ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>,
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)
);
</code></pre>
<h3 id="t54.2 什么是元素">4.2 什么是元素 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t54.2%20%E4%BB%80%E4%B9%88%E6%98%AF%E5%85%83%E7%B4%A0"> # </a></h3>
<ul>
<li>JSX其实只是一种语法糖,最终会通过<a href="https://www.babeljs.cn/repl">babeljs</a>转译成<code>createElement</code>语法</li>
<li>React元素是构成<code>React</code>应用的最小单位</li>
<li>React元素用来描述你在屏幕上看到的内容</li>
<li>React元素事实上是普通的JS对象,ReactDOM来确保浏览器中的DOM数据和React元素保持一致</li>
</ul>
<pre><code class="lang-js">&lt;h1 className="title" style={{color:'red'}}&gt;hello&lt;/h1&gt;
</code></pre>
<pre><code class="lang-js">React.createElement(<span class="hljs-string">"h1"</span>, {
  <span class="hljs-attr">className</span>: <span class="hljs-string">"title"</span>,
  <span class="hljs-attr">style</span>: {
    <span class="hljs-attr">color</span>: <span class="hljs-string">'red'</span>
  }
}, <span class="hljs-string">"hello"</span>);
</code></pre>
<p>createElement的结果</p>
<pre><code class="lang-js">{
  <span class="hljs-attr">type</span>:<span class="hljs-string">'h1'</span>,
  <span class="hljs-attr">props</span>:{
    <span class="hljs-attr">className</span>: <span class="hljs-string">"title"</span>,
    <span class="hljs-attr">style</span>: {
      <span class="hljs-attr">color</span>: <span class="hljs-string">'red'</span>
    }
  },
  <span class="hljs-attr">children</span>:<span class="hljs-string">"hello"</span>
}
</code></pre>
<h3 id="t64.3 JSX表达式">4.3 JSX表达式 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t64.3%20JSX%E8%A1%A8%E8%BE%BE%E5%BC%8F"> # </a></h3>
<ul>
<li>可以任意地在 JSX 当中使用 JavaScript 表达式，在 JSX 当中的表达式要包含在大括号里</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> title: string = <span class="hljs-string">'hello'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
ReactDOM.render&lt;HTMLElement&gt;(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>,
    root
);
</code></pre>
<h3 id="t74.4 JSX属性">4.4 JSX属性 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t74.4%20JSX%E5%B1%9E%E6%80%A7"> # </a></h3>
<ul>
<li>需要注意的是JSX并不是<code>HTML</code>,更像<code>JavaScript</code></li>
<li>在JSX中属性不能包含关键字，像<code>class</code>需要写成<code>className</code>,<code>for</code>需要写成<code>htmlFor</code>,并且属性名需要采用驼峰命名法</li>
</ul>
<pre><code class="lang-js">import React from 'react';
import ReactDOM from 'react-dom';
let title: string = 'hello';
let root: HTMLElement | null = document.getElementById('root');

ReactDOM.render&lt;HTMLElement&gt;(
    &lt;h1 className="title" style={{ color: 'red' }}&gt;Hello&lt;/h1&gt;,
    document.getElementById('root')
);
 */
</code></pre>
<h3 id="t84.5 JSX也是对象">4.5 JSX也是对象 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t84.5%20JSX%E4%B9%9F%E6%98%AF%E5%AF%B9%E8%B1%A1"> # </a></h3>
<ul>
<li>可以在<code>if</code>或者 <code>for</code>语句里使用<code>JSX</code></li>
<li>将它赋值给变量，当作参数传入，作为返回值都可以</li>
</ul>
<p>if中使用</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greeting</span>(<span class="hljs-params">name: string</span>): <span class="hljs-title">React</span>.<span class="hljs-title">ReactElement</span> </span>{
    <span class="hljs-keyword">if</span> (name) {
        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {name}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
    }
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, Stranger.<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}

<span class="hljs-keyword">const</span> element: React.ReactElement = greeting(<span class="hljs-string">'zhufeng'</span>);

ReactDOM.render(
    element,
    root
);
</code></pre>
<p>for中使用</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
<span class="hljs-keyword">let</span> names: <span class="hljs-built_in">Array</span>&lt;string&gt; = [<span class="hljs-string">'张三'</span>, <span class="hljs-string">'李四'</span>, <span class="hljs-string">'王五'</span>];
<span class="hljs-keyword">let</span> elements: <span class="hljs-built_in">Array</span>&lt;React.ReactElement&gt; = [];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; names.length; i++) {
    elements.push(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>{names[i]}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>);
}
ReactDOM.render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {elements}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>,
    root
);
</code></pre>
<h3 id="t94.6 更新元素渲染">4.6 更新元素渲染 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t94.6%20%E6%9B%B4%E6%96%B0%E5%85%83%E7%B4%A0%E6%B8%B2%E6%9F%93"> # </a></h3>
<ul>
<li>React 元素都是<code>immutable</code>不可变的。当元素被创建之后，你是无法改变其内容或属性的。一个元素就好像是动画里的一帧，它代表应用界面在某一时间点的样子</li>
<li>更新界面的唯一办法是创建一个新的元素，然后将它传入<code>ReactDOM.render()</code>方法</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tick</span>(<span class="hljs-params"></span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-keyword">const</span> element: React.ReactElement = (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            {new Date().toLocaleTimeString()}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
    ReactDOM.render(element, root);
}
setInterval(tick, <span class="hljs-number">1000</span>);
</code></pre>
<h3 id="t104.7 React只会更新必要的部分">4.7 React只会更新必要的部分 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t104.7%20React%E5%8F%AA%E4%BC%9A%E6%9B%B4%E6%96%B0%E5%BF%85%E8%A6%81%E7%9A%84%E9%83%A8%E5%88%86"> # </a></h3>
<ul>
<li>React DOM 首先会比较元素内容先后的不同，而在渲染过程中只会更新改变了的部分。</li>
<li>即便我们每秒都创建了一个描述整个UI树的新元素，React DOM 也只会更新渲染文本节点中发生变化的内容</li>
</ul>
<h2 id="t115. 组件 &amp; Props">5. 组件 &amp; Props <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t115.%20%E7%BB%84%E4%BB%B6%20&amp;%20Props"> # </a></h2>
<ul>
<li>可以将UI切分成一些独立的、可复用的部件，这样你就只需专注于构建每一个单独的部件</li>
<li>组件从概念上类似于 JavaScript 函数。它接受任意的入参（即 “props”），并返回用于描述页面展示内容的 React 元素</li>
</ul>
<h3 id="t125.1 函数(定义的)组件">5.1 函数(定义的)组件 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t125.1%20%E5%87%BD%E6%95%B0(%E5%AE%9A%E4%B9%89%E7%9A%84)%E7%BB%84%E4%BB%B6"> # </a></h3>
<ul>
<li>函数组件接收一个单一的<code>props</code>对象并返回了一个React元素</li>
</ul>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Welcome</span>(<span class="hljs-params">props: Props</span>): <span class="hljs-title">React</span>.<span class="hljs-title">ReactElement</span> </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
</code></pre>
<h3 id="t135.2 类(定义的)组件">5.2 类(定义的)组件 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t135.2%20%E7%B1%BB(%E5%AE%9A%E4%B9%89%E7%9A%84)%E7%BB%84%E4%BB%B6"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Welcome</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>&gt; </span>{
    render(): React.ReactElement {
        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {this.props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
    }
}
</code></pre>
<h3 id="t145.3 组件渲染">5.3 组件渲染 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t145.3%20%E7%BB%84%E4%BB%B6%E6%B8%B2%E6%9F%93"> # </a></h3>
<ul>
<li>React元素不但可以是DOM标签，还可以是用户自定义的组件</li>
<li>当 React 元素为用户自定义组件时，它会将 JSX 所接收的属性（attributes）转换为单个对象传递给组件，这个对象被称之为 <code>props</code></li>
<li>组件名称必须以大写字母开头</li>
<li>组件必须在使用的时候定义或引用它</li>
<li>组件的返回值只能有一个根元素</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
interface Props {
    <span class="hljs-attr">name</span>: string;
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Welcome</span>(<span class="hljs-params">props: Props</span>): <span class="hljs-title">React</span>.<span class="hljs-title">ReactElement</span> </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Welcome2</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>&gt; </span>{
    render(): React.ReactElement {
        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {this.props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
    }
}

<span class="hljs-keyword">const</span> element1: React.ReactElement&lt;Props, React.JSXElementConstructor&lt;Props&gt;&gt; = &lt;Welcome name="zhufeng" /&gt;;
console.log(element1.props.name);
const element2: React.ReactElement&lt;Props, React.JSXElementConstructor&lt;Props&gt;&gt; = &lt;Welcome2 name="zhufeng" /&gt;;
console.log(element1.props.name);

ReactDOM.render(
    &lt;div&gt;{element1}{element2}&lt;/div&gt;,
    root
);
</code></pre>
<h3 id="t155.4 复合组件 &amp; 提取组件">5.4 复合组件 &amp; 提取组件 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t155.4%20%E5%A4%8D%E5%90%88%E7%BB%84%E4%BB%B6%20&amp;%20%E6%8F%90%E5%8F%96%E7%BB%84%E4%BB%B6"> # </a></h3>
<ul>
<li>组件由于嵌套变得难以被修改，可复用的部分也难以被复用，所以可以把大组件切分为更小的组件</li>
<li>当你的UI中有一部分重复使用了好几次(比如<code>Button</code>、<code>Panel</code>、<code>Avatar</code>)，或者其自身就足够复杂(比如，App)，类似这些都是抽象成可复用组件的绝佳选择</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);

interface PanelProps {
    <span class="hljs-attr">header</span>: string;
    body: string;
}
interface HeaderProps {
    <span class="hljs-attr">header</span>: string;
}
interface BodyProps {
    <span class="hljs-attr">body</span>: string;
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Panel</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">PanelProps</span>&gt; </span>{
    render(): React.ReactElement {
        <span class="hljs-keyword">let</span> { header, body } = <span class="hljs-keyword">this</span>.props;
        <span class="hljs-keyword">return</span> (
            &lt;div style={{ border: '1px solid red', padding: 5 }}&gt;
                &lt;div className="panel-default panel"&gt;
                    &lt;Header header={header}&gt;&lt;/Header&gt;
                    &lt;Body body={body} /&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        )
    }
}
class Header extends React.Component&lt;HeaderProps&gt; {
    render(): React.ReactElement {
        return (
            &lt;div style={{ border: '1px solid green' }}&gt;
                {this.props.header}
            &lt;/div&gt;
        )
    }
}
class Body extends React.Component&lt;BodyProps&gt; {
    render(): React.ReactElement {
        return (
            &lt;div style={{ border: '1px solid blue' }}&gt;
                {this.props.body}
            &lt;/div&gt;
        )
    }
}

let data: PanelProps = { header: '头部', body: '身体' };
ReactDOM.render(&lt;Panel {...data} /&gt;, root);
</code></pre>
<h3 id="t165.5 Props的只读性">5.5 Props的只读性 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t165.5%20Props%E7%9A%84%E5%8F%AA%E8%AF%BB%E6%80%A7"> # </a></h3>
<ul>
<li>无论是使用函数或是类来声明一个组件，它决不能修改它自己的<code>props</code></li>
<li><code>纯函数</code>没有改变它自己的输入值，当传入的值相同时，总是会返回相同的结果</li>
<li>所有的React组件必须像纯函数那样使用它们的props</li>
</ul>
<pre><code class="lang-js"><span class="hljs-comment">//纯函数</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">a, b</span>) </span>{
  <span class="hljs-keyword">return</span> a + b;
}
<span class="hljs-comment">//非纯函数</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params">account, amount</span>) </span>{
  account.total -= amount;
}
</code></pre>
<h3 id="t175.6  类型检查">5.6  类型检查 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t175.6%20%20%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5"> # </a></h3>
<ul>
<li>要在组件的 <code>props</code> 上进行类型检查，你只需配置特定的 <code>propTypes</code> 属性</li>
<li>您可以通过配置特定的 <code>defaultProps</code> 属性来定义 props 的默认值：</li>
</ul>
<table>
<thead>
<tr>
<th>用法</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>PropTypes.array</td>
<td>数组</td>
</tr>
<tr>
<td>PropTypes.bool</td>
<td>布尔类型</td>
</tr>
<tr>
<td>PropTypes.func</td>
<td>函数</td>
</tr>
<tr>
<td>PropTypes.number</td>
<td>数字</td>
</tr>
<tr>
<td>PropTypes.object</td>
<td>对象</td>
</tr>
<tr>
<td>PropTypes.string</td>
<td>字符串</td>
</tr>
<tr>
<td>PropTypes.symbol</td>
<td>Symbol</td>
</tr>
<tr>
<td>PropTypes.node</td>
<td>任何可被渲染的元素(包括数字、字符串、元素或数组)</td>
</tr>
<tr>
<td>PropTypes.element</td>
<td>一个 React 元素</td>
</tr>
<tr>
<td>PropTypes.instanceOf(Message)</td>
<td>Message类的实例</td>
</tr>
<tr>
<td>PropTypes.oneOf(['News', 'Photos'])</td>
<td>枚举类型</td>
</tr>
<tr>
<td>PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.instanceOf(Message)])</td>
<td>几种类型中的任意一个类型</td>
</tr>
<tr>
<td>PropTypes.arrayOf(PropTypes.number)</td>
<td>一个数组由某一类型的元素组成</td>
</tr>
<tr>
<td>PropTypes.objectOf(PropTypes.number)</td>
<td>可以指定一个对象由某一类型的值组成</td>
</tr>
<tr>
<td>PropTypes.shape({color: PropTypes.string,fontSize: PropTypes.number})</td>
<td>可以指定一个对象由特定的类型值组成</td>
</tr>
<tr>
<td>PropTypes.func.isRequired</td>
<td>你可以在任何 PropTypes 属性后面加上 <code>isRequired</code> ，确保这个 prop 没有被提供时，会打印警告信息</td>
</tr>
<tr>
<td>PropTypes.any.isRequired</td>
<td>任意类型的数据</td>
</tr>
<tr>
<td>customProp: function(props, propName, componentName){}</td>
<td>你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象</td>
</tr>
</tbody>
</table>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
interface PersonProps {
    name?: string;
    age?: number,
    gender?: <span class="hljs-string">'male'</span> | <span class="hljs-string">'female'</span>,
    hobby?: <span class="hljs-built_in">Array</span>&lt;string&gt;,
    position?: { <span class="hljs-attr">x</span>: number, <span class="hljs-attr">y</span>: number },
    friends?: <span class="hljs-built_in">Array</span>&lt;{ <span class="hljs-attr">name</span>: string, <span class="hljs-attr">age</span>: number }&gt;,
    [prop: string]: any
}
<span class="hljs-keyword">let</span> root: HTMLElement | <span class="hljs-literal">null</span> = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>);
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">PersonProps</span>&gt; </span>{
    <span class="hljs-keyword">static</span> defaultProps: PersonProps = {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'Stranger'</span>
    }
    <span class="hljs-keyword">static</span> propTypes = {
        <span class="hljs-attr">name</span>: PropTypes.string.isRequired,
        <span class="hljs-attr">gender</span>: PropTypes.oneOf([<span class="hljs-string">'male'</span>, <span class="hljs-string">'female'</span>]),
        <span class="hljs-attr">hobby</span>: PropTypes.arrayOf(PropTypes.string),
        <span class="hljs-attr">position</span>: PropTypes.shape({
            <span class="hljs-attr">x</span>: PropTypes.number,
            <span class="hljs-attr">y</span>: PropTypes.number
        }),
        age(props: PersonProps, <span class="hljs-attr">propName</span>: string, <span class="hljs-attr">componentName</span>: string) {
            <span class="hljs-keyword">let</span> age = props[propName];
            <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span> || age &gt; <span class="hljs-number">120</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Invalid Prop <span class="hljs-subst">${propName}</span> supplied to <span class="hljs-subst">${componentName}</span>`</span>)
            }
        },
        <span class="hljs-attr">friends</span>: PropTypes.arrayOf((propValue: any, <span class="hljs-attr">key</span>: string, <span class="hljs-attr">componentName</span>: string, <span class="hljs-attr">location</span>: string, <span class="hljs-attr">propFullName</span>: string): <span class="hljs-built_in">Error</span> | <span class="hljs-function"><span class="hljs-params">null</span> =&gt;</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'propValue='</span> + <span class="hljs-built_in">JSON</span>.stringify(propValue, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>), <span class="hljs-string">"key="</span> + key, <span class="hljs-string">"componentName="</span> + componentName, <span class="hljs-string">"location="</span> + location, <span class="hljs-string">"propFullName="</span> + propFullName);
            <span class="hljs-comment">/**
             * propValue=[{ name: 'zhangsan', age: 10 }, { name: 'lisi', age: -20 }] key=0 componentName=Person location=prop propFullName=friends[0]
             * propValue=[{ name: 'zhangsan', age: 10 }, { name: 'lisi', age: -20 }] key=1 componentName=Person location=prop propFullName=friends[1]
             */</span>
            <span class="hljs-keyword">let</span> age = propValue[key].age;
            <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span> || age &gt; <span class="hljs-number">120</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
                    <span class="hljs-string">'Invalid prop `'</span> + propFullName + <span class="hljs-string">'.age` supplied to'</span> +
                    <span class="hljs-string">' `'</span> + componentName + <span class="hljs-string">'`. Validation failed.'</span>
                );
            }
            <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
        })
    }
    render() {
        <span class="hljs-keyword">let</span> { name, age, gender, hobby, position } = <span class="hljs-keyword">this</span>.props;
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>姓名<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>年龄<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>性别<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>爱好<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>位置<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{name}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{age}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{gender}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{hobby!.join(',')}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{position!.x + ' ' + position!.y}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span></span>
        )
    }
}
<span class="hljs-keyword">let</span> personProps: PersonProps = {
    <span class="hljs-attr">age</span>: <span class="hljs-number">80</span>,
    <span class="hljs-attr">gender</span>: <span class="hljs-string">'male'</span>,
    <span class="hljs-attr">hobby</span>: [<span class="hljs-string">'basketball'</span>, <span class="hljs-string">'football'</span>],
    <span class="hljs-attr">position</span>: { <span class="hljs-attr">x</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">10</span> },
    <span class="hljs-attr">friends</span>: [{ <span class="hljs-attr">name</span>: <span class="hljs-string">'zhangsan'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">10</span> }, { <span class="hljs-attr">name</span>: <span class="hljs-string">'lisi'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">-20</span> }]
}
ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Person</span> {<span class="hljs-attr">...personProps</span>} /&gt;</span>, root);
</span></code></pre>
<h2 id="t186. 虚拟DOM">6. 虚拟DOM <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t186.%20%E8%99%9A%E6%8B%9FDOM"> # </a></h2>
<h3 id="t196.1 src\index.tsx">6.1 src\index.tsx <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t196.1%20src\index.tsx"> # </a></h3>
<p>src\index.tsx</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'./react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'./react-dom'</span>;
<span class="hljs-keyword">import</span> { FunctionComponentElement, ComponentElement } <span class="hljs-keyword">from</span> <span class="hljs-string">'./typings'</span>;
<span class="hljs-comment">//let element = &lt;h1 className="title" style={{color:'red',fontSize:'24px'}}&gt;&lt;/h1&gt;</span>
<span class="hljs-comment">//let element = React.createElement('h1', { className: 'title', style: { color: 'red', fontSize: '50px' } }, 'hello');</span>
<span class="hljs-comment">//console.log(JSON.stringify(element));</span>
interface Props {
    <span class="hljs-attr">title</span>: string
}
<span class="hljs-comment">/* 
function Welcome(props: Props) {
    return React.createElement('h1', { className: 'title' }, props.title);
} 
let element: FunctionComponentElement&lt;Props&gt; = React.createElement&lt;Props&gt;(Welcome, { title: '标题' }) as FunctionComponentElement&lt;Props&gt;;
*/</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Welcome</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    render() {
        <span class="hljs-keyword">return</span> React.createElement(<span class="hljs-string">'h1'</span>, { <span class="hljs-attr">className</span>: <span class="hljs-string">'title'</span> }, <span class="hljs-keyword">this</span>.props.title);
    }
}
<span class="hljs-keyword">let</span> element: ComponentElement&lt;Props&gt; = React.createElement&lt;Props&gt;(Welcome, { <span class="hljs-attr">title</span>: <span class="hljs-string">'标题'</span> }) <span class="hljs-keyword">as</span> ComponentElement&lt;Props&gt;;
ReactDOM.render&lt;Props&gt;(element, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>) <span class="hljs-keyword">as</span> HTMLElement);
</code></pre>
<h3 id="t206.2 src\react.tsx">6.2 src\react.tsx <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t206.2%20src\react.tsx"> # </a></h3>
<p>src\react.tsx</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { FunctionComponent, ComponentClass, ReactElement, PropsWithChildren, Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'./typings'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createElement</span>&lt;<span class="hljs-title">P</span>&gt;(<span class="hljs-params">type: string | FunctionComponent&lt;P&gt; | ComponentClass&lt;P&gt;, config: P, ...children: Array&lt;ReactElement | string&gt;</span>): <span class="hljs-title">ReactElement</span>&lt;<span class="hljs-title">P</span>&gt; </span>{
    <span class="hljs-keyword">let</span> props = { ...config, children };
    <span class="hljs-keyword">const</span> element: ReactElement&lt;PropsWithChildren&lt;P&gt;, FunctionComponent&lt;PropsWithChildren&lt;P&gt;&gt; | ComponentClass&lt;PropsWithChildren&lt;P&gt;&gt; | string&gt; = {
        <span class="hljs-attr">type</span>: type, props,
    };
    <span class="hljs-keyword">return</span> element;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    createElement, Component
}
</code></pre>
<h3 id="t216.3 src\typings.tsx">6.3 src\typings.tsx <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t216.3%20src\typings.tsx"> # </a></h3>
<p>src\typings.tsx</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> interface Component&lt;P = any&gt; {
    render(): ReactElement
}
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Component</span>&lt;<span class="hljs-title">P</span> </span>= any&gt; {
    <span class="hljs-keyword">static</span> isReactComponent: boolean = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">constructor</span>(public props: P) {
        <span class="hljs-keyword">this</span>.props = props;
    }
}

<span class="hljs-keyword">export</span> type JSXElementConstructor&lt;P&gt; = <span class="hljs-function">(<span class="hljs-params">(props: P</span>) =&gt;</span> ReactElement) | <span class="hljs-function">(<span class="hljs-params"><span class="hljs-keyword">new</span> (props: P</span>) =&gt;</span> Component&lt;P&gt;);

<span class="hljs-keyword">export</span> interface ReactElement&lt;P = any, T extends string | JSXElementConstructor&lt;any&gt; = string | JSXElementConstructor&lt;any&gt;&gt; {
    <span class="hljs-attr">type</span>: T;
    props: P;
}
<span class="hljs-keyword">export</span> type PropsWithChildren&lt;P&gt; = P &amp; { children?: <span class="hljs-built_in">Array</span>&lt;ReactElement | string&gt; };
<span class="hljs-keyword">export</span> interface FunctionComponent&lt;P = {}&gt; {
    (props: PropsWithChildren&lt;P&gt;): ReactElement;
}

<span class="hljs-keyword">export</span> interface ComponentClass&lt;P = {}&gt; {
    <span class="hljs-keyword">new</span>(props: P, context?: any): Component&lt;P&gt;;
}
<span class="hljs-keyword">export</span> interface FunctionComponentElement&lt;P&gt; extends ReactElement&lt;P, FunctionComponent&lt;P&gt;&gt; {

}
<span class="hljs-keyword">export</span> interface ComponentElement&lt;P&gt; extends ReactElement&lt;P, ComponentClass&lt;P&gt;&gt; {

}
<span class="hljs-keyword">export</span> interface CSSProperties extends Record&lt;string, any&gt; {
    [key: string]: any
}
<span class="hljs-keyword">export</span> interface HTMLAttributes {
    className?: string;
    style?: CSSProperties;
}
</code></pre>
<h3 id="t226.4 src\react-dom.tsx">6.4 src\react-dom.tsx <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t226.4%20src\react-dom.tsx"> # </a></h3>
<p>src\react-dom.tsx</p>
<pre><code class="lang-js">
<span class="hljs-keyword">import</span> { FunctionComponent, ComponentClass, ReactElement, PropsWithChildren, HTMLAttributes } <span class="hljs-keyword">from</span> <span class="hljs-string">'./typings'</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>&lt;<span class="hljs-title">P</span>&gt;(<span class="hljs-params">element: ReactElement&lt;PropsWithChildren&lt;P&gt;, FunctionComponent&lt;PropsWithChildren&lt;P&gt;&gt; | ComponentClass&lt;PropsWithChildren&lt;P&gt;&gt; | string&gt; | string, container: HTMLElement</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> element == <span class="hljs-string">'string'</span>) {
        <span class="hljs-keyword">return</span> container!.appendChild(<span class="hljs-built_in">document</span>.createTextNode(element))
    }
    <span class="hljs-keyword">let</span> type, <span class="hljs-attr">props</span>: HTMLAttributes &amp; P &amp; Record&lt;string, any&gt;;
    type = element.type;
    props = element.props;
    <span class="hljs-keyword">if</span> ((type <span class="hljs-keyword">as</span> any).isReactComponent) {<span class="hljs-comment">//如果为true说明它是一个类组件</span>
        element = <span class="hljs-keyword">new</span> (type <span class="hljs-keyword">as</span> ComponentClass&lt;PropsWithChildren&lt;P&gt;&gt;)(props <span class="hljs-keyword">as</span> PropsWithChildren&lt;P&gt;).render();
        type = element.type;
        props = element.props;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> type == <span class="hljs-string">'function'</span>) {
        element = (type <span class="hljs-keyword">as</span> FunctionComponent&lt;P&gt;)(props);
        type = element.type;
        props = element.props;
    }
    <span class="hljs-keyword">let</span> domElement = <span class="hljs-built_in">document</span>.createElement(type <span class="hljs-keyword">as</span> string);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> propName <span class="hljs-keyword">in</span> props) {
        <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'children'</span>) {
            <span class="hljs-keyword">let</span> children: <span class="hljs-built_in">Array</span>&lt;ReactElement | string&gt; | <span class="hljs-literal">undefined</span> = props.children;
            <span class="hljs-keyword">if</span> (children) {
                children.forEach(<span class="hljs-function">(<span class="hljs-params">child: ReactElement | string</span>) =&gt;</span> render(child, domElement));
            }
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'className'</span>) {
            <span class="hljs-keyword">if</span> (props.className)
                domElement.className = props.className;
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'style'</span>) {
            <span class="hljs-keyword">let</span> styleObj = props.style;
            <span class="hljs-comment">/**
            for(let attr in styleObj){
                domElement.style[attr] =  styleObj[attr];
            }
             */</span>
            <span class="hljs-keyword">if</span> (styleObj) {
                <span class="hljs-keyword">let</span> cssText = <span class="hljs-built_in">Object</span>.keys(styleObj).map(<span class="hljs-function"><span class="hljs-params">attr</span> =&gt;</span> {
                    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${attr.replace(<span class="hljs-regexp">/([A-Z])/g</span>, <span class="hljs-keyword">function</span> () { <span class="hljs-keyword">return</span> <span class="hljs-string">"-"</span> + <span class="hljs-built_in">arguments</span>[<span class="hljs-number">1</span>] }</span>)}:<span class="hljs-subst">${styleObj![attr]}</span>`</span>;
                }).join(<span class="hljs-string">';'</span>);
                domElement.style.cssText = cssText;
            }

        } <span class="hljs-keyword">else</span> {
            domElement.setAttribute(propName, props[propName]);
        }
    }
    container!.appendChild(domElement);
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> { render };
</code></pre>
<h2 id="t236. 状态">6. 状态 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t236.%20%E7%8A%B6%E6%80%81"> # </a></h2>
<ul>
<li>组件的数据来源有两个地方，分别是属性对象和状态对象</li>
<li>属性是父组件传递过来的(默认属性，属性校验) </li>
<li>状态是自己内部的,改变状态唯一的方式就是<code>setState</code></li>
<li>属性和状态的变化都会影响视图更新</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props {

}
interface State {
    <span class="hljs-attr">date</span>: any
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Clock</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt;</span>{
    timerID
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">date</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>() };
    }

    componentDidMount() {
        <span class="hljs-keyword">this</span>.timerID = setInterval(
            <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">this</span>.tick(),
            <span class="hljs-number">1000</span>
        );
    }

    componentWillUnmount() {
        clearInterval(<span class="hljs-keyword">this</span>.timerID);
    }

    tick() {
        <span class="hljs-keyword">this</span>.setState({
            <span class="hljs-attr">date</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
        });
    }

    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, world!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>It is {this.state.date.toLocaleTimeString()}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Clock</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t246.1 不要直接修改 State">6.1 不要直接修改 State <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t246.1%20%E4%B8%8D%E8%A6%81%E7%9B%B4%E6%8E%A5%E4%BF%AE%E6%94%B9%20State"> # </a></h3>
<ul>
<li>构造函数是唯一可以给 <code>this.state</code> 赋值的地方</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props {
}
interface State {
    <span class="hljs-attr">number</span>: number
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    timerID
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = {
            <span class="hljs-attr">number</span>: <span class="hljs-number">0</span>
        };
    }

    componentDidMount() {
        <span class="hljs-keyword">this</span>.timerID = setInterval(
            <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
                <span class="hljs-keyword">this</span>.setState({ <span class="hljs-attr">number</span>: <span class="hljs-keyword">this</span>.state.number + <span class="hljs-number">1</span> });
                <span class="hljs-comment">//this.state.number = this.state.number + 1;</span>
            },
            <span class="hljs-number">1000</span>
        );
    }

    componentWillUnmount() {
        clearInterval(<span class="hljs-keyword">this</span>.timerID);
    }

    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> &gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span> {this.state.number} <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;
    <span class="hljs-attr">Counter</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t256.2 State 的更新可能是异步的">6.2 State 的更新可能是异步的 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t256.2%20State%20%E7%9A%84%E6%9B%B4%E6%96%B0%E5%8F%AF%E8%83%BD%E6%98%AF%E5%BC%82%E6%AD%A5%E7%9A%84"> # </a></h3>
<ul>
<li>出于性能考虑，React 可能会把多个 setState() 调用合并成一个调用</li>
<li>因为 this.props 和 this.state 可能会异步更新，所以你不要依赖他们的值来更新下一个状态</li>
<li>可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props {
}
interface State {
    <span class="hljs-attr">number</span>: number
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = {
            <span class="hljs-attr">number</span>: <span class="hljs-number">0</span>
        };
    }
    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-comment">//this.setState({number:this.state.number+1});</span>
        <span class="hljs-comment">//console.log(this.state.number);</span>
        <span class="hljs-comment">//this.setState({number:this.state.number+1});</span>

        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> (
            { <span class="hljs-attr">number</span>: state.number + <span class="hljs-number">1</span> }
        ));
        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> (
            { <span class="hljs-attr">number</span>: state.number + <span class="hljs-number">1</span> }
        ));
    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> &gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span> {this.state.number} <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;
    <span class="hljs-attr">Counter</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t266.3 State 的更新会被合并">6.3 State 的更新会被合并 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t266.3%20State%20%E7%9A%84%E6%9B%B4%E6%96%B0%E4%BC%9A%E8%A2%AB%E5%90%88%E5%B9%B6"> # </a></h3>
<ul>
<li>当你调用 setState() 的时候，React 会把你提供的对象合并到当前的 state</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props {

}
interface State {
    <span class="hljs-attr">name</span>: string;
    number: number
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = {
            <span class="hljs-attr">name</span>: <span class="hljs-string">'zhufeng'</span>,
            <span class="hljs-attr">number</span>: <span class="hljs-number">0</span>
        };
    }
    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-comment">//this.setState({number:this.state.number+1});</span>
        <span class="hljs-comment">//console.log(this.state.number);</span>
        <span class="hljs-comment">//this.setState({number:this.state.number+1});</span>

        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> (
            { <span class="hljs-attr">number</span>: state.number + <span class="hljs-number">1</span> }
        ));
        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> (
            { <span class="hljs-attr">number</span>: state.number + <span class="hljs-number">1</span> }
        ));
    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> &gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.state.name}: {this.state.number} <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;
    <span class="hljs-attr">Counter</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t276.4 数据是向下流动的">6.4 数据是向下流动的 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t276.4%20%E6%95%B0%E6%8D%AE%E6%98%AF%E5%90%91%E4%B8%8B%E6%B5%81%E5%8A%A8%E7%9A%84"> # </a></h3>
<ul>
<li>不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的，并且它们也并不关心它是函数组件还是 class 组件</li>
<li>这就是为什么称 state 为局部的或是封装的的原因,除了拥有并设置了它的组件，其他组件都无法访问</li>
<li>任何的 state 总是所属于特定的组件，而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件</li>
<li>如果你把一个以组件构成的树想象成一个 props 的数据瀑布的话，那么每一个组件的 state 就像是在任意一点上给瀑布增加额外的水源，但是它只能向下流动</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props {

}
interface State {
    <span class="hljs-attr">name</span>: string;
    number: number
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = {
            <span class="hljs-attr">name</span>: <span class="hljs-string">'zhufeng'</span>,
            <span class="hljs-attr">number</span>: <span class="hljs-number">0</span>
        };
    }
    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> (
            { <span class="hljs-attr">number</span>: state.number + <span class="hljs-number">1</span> }
        ));
    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">border:</span> '<span class="hljs-attr">1px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">red</span>' }}&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.state.name}: {this.state.number} <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SubCounter</span> <span class="hljs-attr">number</span>=<span class="hljs-string">{this.state.number}</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        );
    }
}
class SubCounter extends React.Component<span class="hljs-tag">&lt;<span class="hljs-name">{</span> <span class="hljs-attr">number:</span> <span class="hljs-attr">number</span> }&gt;</span> {
    render() {
        return <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">border:</span> '<span class="hljs-attr">1px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">blue</span>' }}&gt;</span>子计数器:{this.props.number}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>;
    }
}
ReactDOM.render(
    <span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h2 id="t287. 事件处理">7. 事件处理 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t287.%20%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86"> # </a></h2>
<ul>
<li>React 事件的命名采用小驼峰式（camelCase），而不是纯小写。</li>
<li>使用 JSX 语法时你需要传入一个函数作为事件处理函数，而不是一个字符串</li>
<li>你不能通过返回 <code>false</code> 的方式阻止默认行为。你必须显式的使用<code>preventDefault</code></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Link</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    handleClick(e: React.MouseEvent) {
        e.preventDefault();
        alert(<span class="hljs-string">'The link was clicked.'</span>);
    }

    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"http://www.baidu.com"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>
                Click me
          <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Link</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t297.2 this">7.2 this <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t297.2%20this"> # </a></h3>
<ul>
<li>你必须谨慎对待 JSX 回调函数中的 this,可以使用:<ul>
<li>公共属性(箭头函数)</li>
<li>匿名函数</li>
<li>bind进行绑定</li>
</ul>
</li>
</ul>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoggingButton</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    handleClick() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is:'</span>, <span class="hljs-keyword">this</span>);
    }
    handleClick1 = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is:'</span>, <span class="hljs-keyword">this</span>);
    }
    render() {
        <span class="hljs-comment">//onClick={this.handleClick.bind(this)</span>
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{(event)</span> =&gt;</span> this.handleClick(event)}&gt;
                Click me
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
        );
    }
}
</code></pre>
<h3 id="t307.3 向事件处理程序传递参数">7.3 向事件处理程序传递参数 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t307.3%20%E5%90%91%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%E7%A8%8B%E5%BA%8F%E4%BC%A0%E9%80%92%E5%8F%82%E6%95%B0"> # </a></h3>
<ul>
<li>匿名函数</li>
<li>bind</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoggingButton</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    handleClick = <span class="hljs-function">(<span class="hljs-params">id, event: React.MouseEvent</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'id:'</span>, id);
    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{(event)</span> =&gt;</span> this.handleClick('1', event)}&gt;
                    Click me
            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick.bind(this,</span> '<span class="hljs-attr">1</span>')}&gt;</span>
                    Click me
            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/&gt;</span>
        );
    }
}
ReactDOM.render(
    <span class="hljs-tag">&lt;<span class="hljs-name">LoggingButton</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h3 id="t317.4 Ref">7.4 Ref <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t317.4%20Ref"> # </a></h3>
<ul>
<li>Refs 提供了一种方式，允许我们访问 DOM 节点或在 render 方法中创建的 React 元素</li>
<li>在 React 渲染生命周期时，表单元素上的 value 将会覆盖 DOM 节点中的值，在非受控组件中，你经常希望 React 能赋予组件一个初始值，但是不去控制后续的更新。 在这种情况下, 你可以指定一个 defaultValue 属性，而不是 <code>value</code></li>
</ul>
<h4 id="t327.4.1 ref的值是一个字符串">7.4.1 ref的值是一个字符串 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t327.4.1%20ref%E7%9A%84%E5%80%BC%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2"> # </a></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sum</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    handleAdd = <span class="hljs-function">(<span class="hljs-params">event: React.MouseEvent</span>) =&gt;</span> {
        <span class="hljs-keyword">let</span> a = (<span class="hljs-keyword">this</span>.refs.a <span class="hljs-keyword">as</span> HTMLInputElement).value;
        <span class="hljs-keyword">let</span> b = (<span class="hljs-keyword">this</span>.refs.b <span class="hljs-keyword">as</span> HTMLInputElement).value;
        (<span class="hljs-keyword">this</span>.refs.c <span class="hljs-keyword">as</span> HTMLInputElement).value = a + b;
    }

    render() {
        <span class="hljs-keyword">return</span> (
            &lt;&gt;
                &lt;input ref="a" /&gt;+&lt;input ref="b" /&gt;&lt;button onClick={this.handleAdd}&gt;=&lt;/button&gt;&lt;input ref="c" /&gt;
            &lt;/&gt;
        );
    }
}
ReactDOM.render(
    &lt;Sum /&gt;,
    document.getElementById('root')
);
</code></pre>
<h4 id="t337.4.2 ref的值是一个函数">7.4.2 ref的值是一个函数 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t337.4.2%20ref%E7%9A%84%E5%80%BC%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0"> # </a></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sum</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    a
    b
    result
    handleAdd = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        <span class="hljs-keyword">let</span> a = <span class="hljs-keyword">this</span>.a.value;
        <span class="hljs-keyword">let</span> b = <span class="hljs-keyword">this</span>.b.value;
        <span class="hljs-keyword">this</span>.result.value = a + b;
    }
    render() {
        <span class="hljs-keyword">return</span> (
            &lt;&gt;
                &lt;input ref={ref =&gt; this.a = ref} /&gt;+&lt;input ref={ref =&gt; this.b = ref} /&gt;&lt;button onClick={this.handleAdd}&gt;=&lt;/button&gt;&lt;input ref={ref =&gt; this.result = ref} /&gt;
            &lt;/&gt;
        );
    }
}
ReactDOM.render(
    &lt;Sum /&gt;,
    document.getElementById('root')
);
</code></pre>
<h4 id="t347.4.3 为 DOM 元素添加 ref">7.4.3 为 DOM 元素添加 ref <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t347.4.3%20%E4%B8%BA%20DOM%20%E5%85%83%E7%B4%A0%E6%B7%BB%E5%8A%A0%20ref"> # </a></h4>
<ul>
<li>可以使用 ref 去存储 DOM 节点的引用</li>
<li>当 ref 属性用于 HTML 元素时，构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sum</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    a
    b
    result
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.a = React.createRef();
        <span class="hljs-keyword">this</span>.b = React.createRef();
        <span class="hljs-keyword">this</span>.result = React.createRef();
    }
    handleAdd = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">let</span> a = <span class="hljs-keyword">this</span>.a.current.value;
        <span class="hljs-keyword">let</span> b = <span class="hljs-keyword">this</span>.b.current.value;
        <span class="hljs-keyword">this</span>.result.current.value = a + b;
    }
    render() {
        <span class="hljs-keyword">return</span> (
            &lt;&gt;
                &lt;input ref={this.a} /&gt;+&lt;input ref={this.b} /&gt;&lt;button onClick={this.handleAdd}&gt;=&lt;/button&gt;&lt;input ref={this.result} /&gt;
            &lt;/&gt;
        );
    }
}
ReactDOM.render(
    &lt;Sum /&gt;,
    document.getElementById('root')
);
</code></pre>
<h4 id="t357.4.4 为 class 组件添加 Ref">7.4.4 为 class 组件添加 Ref <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t357.4.4%20%E4%B8%BA%20class%20%E7%BB%84%E4%BB%B6%E6%B7%BB%E5%8A%A0%20Ref"> # </a></h4>
<ul>
<li>当 ref 属性用于自定义 class 组件时，ref 对象接收组件的挂载实例作为其 current 属性</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Form</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    input
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.input = React.createRef();
    }
    getFocus = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.input.current.getFocus();
    }
    render() {
        <span class="hljs-keyword">return</span> (
            &lt;&gt;
                &lt;TextInput ref={this.input} /&gt;
                &lt;button onClick={this.getFocus}&gt;获得焦点&lt;/button&gt;
            &lt;/&gt;
        );
    }
}
class TextInput extends React.Component {
    input
    constructor(props) {
        super(props);
        this.input = React.createRef();
    }
    getFocus = () =&gt; {
        this.input.current.focus();
    }
    render() {
        return &lt;input ref={this.input} /&gt;
    }
}
ReactDOM.render(
    &lt;Form /&gt;,
    document.getElementById('root')
);
</code></pre>
<h4 id="t367.4.5 Ref转发">7.4.5 Ref转发 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t367.4.5%20Ref%E8%BD%AC%E5%8F%91"> # </a></h4>
<ul>
<li>你不能在函数组件上使用 ref 属性，因为他们没有实例</li>
<li>Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧</li>
<li>Ref 转发允许某些组件接收 ref，并将其向下传递（换句话说，“转发”它）给子组件<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Form</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  input
  <span class="hljs-keyword">constructor</span>(props) {
      <span class="hljs-keyword">super</span>(props);
      <span class="hljs-keyword">this</span>.input = React.createRef();
  }
  getFocus = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      <span class="hljs-keyword">this</span>.input.current.getFocus();
  }
  render() {
      <span class="hljs-keyword">return</span> (
          &lt;&gt;
              &lt;TextInput ref={this.input} /&gt;
              &lt;button onClick={this.getFocus}&gt;获得焦点&lt;/button&gt;
          &lt;/&gt;
      );
  }
}
//Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
function TextInput() {
  return &lt;input /&gt;
}
ReactDOM.render(
  &lt;Form /&gt;,
  document.getElementById('root')
);
</code></pre>
</li>
</ul>
<p>使用forwardRef</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface InputProps { }
<span class="hljs-keyword">const</span> TextInput = React.forwardRef(<span class="hljs-function">(<span class="hljs-params">props: InputProps, ref: React.Ref&lt;HTMLInputElement&gt;</span>) =&gt;</span> (
    &lt;input ref={ref} /&gt;
));
class Form extends React.Component {
    input
    constructor(props) {
        super(props);
        this.input = React.createRef();
    }
    getFocus = () =&gt; {
        console.log(this.input.current);

        this.input.current.focus();
    }
    render() {
        return (
            &lt;&gt;
                &lt;TextInput ref={this.input} /&gt;
                &lt;button onClick={this.getFocus}&gt;获得焦点&lt;/button&gt;
            &lt;/&gt;
        );
    }
}

ReactDOM.render(
    &lt;Form /&gt;,
    document.getElementById('root')
);
</code></pre>
<h2 id="t378.实现">8.实现 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t378.%E5%AE%9E%E7%8E%B0"> # </a></h2>
<h3 id="t388.1 src\index.js">8.1 src\index.js <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t388.1%20src\index.js"> # </a></h3>
<p>src\index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'./react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'./react-dom'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">number</span>: <span class="hljs-number">0</span> };
    }
    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.setState({ <span class="hljs-attr">number</span>: <span class="hljs-keyword">this</span>.state.number + <span class="hljs-number">1</span> });
        <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.state);

    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>number:{this.state.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}
ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> <span class="hljs-attr">title</span>=<span class="hljs-string">"计数器"</span> /&gt;</span>, document.getElementById('root'));
</span></code></pre>
<h3 id="t398.2 react\index.js">8.2 react\index.js <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t398.2%20react\index.js"> # </a></h3>
<p>src\react\index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { _render } <span class="hljs-keyword">from</span> <span class="hljs-string">'../react-dom'</span>;
<span class="hljs-keyword">import</span> { useDebugValue } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createElement</span>(<span class="hljs-params">type, config, ...children</span>) </span>{
    <span class="hljs-keyword">let</span> props = { ...config, children };
    <span class="hljs-keyword">let</span> element = { type, props };
    <span class="hljs-keyword">return</span> element;
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">renderComponent</span>(<span class="hljs-params">componentInstance</span>) </span>{
    <span class="hljs-keyword">const</span> renderElement = componentInstance.render();
    <span class="hljs-keyword">const</span> newDOM = _render(renderElement.type, renderElement.props, componentInstance);
    componentInstance.dom.parentNode.replaceChild(newDOM, componentInstance.dom);
    componentInstance.dom = newDOM;
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Component</span> </span>{
    <span class="hljs-keyword">static</span> isReactComponent = <span class="hljs-literal">true</span>
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">this</span>.props = props;
        <span class="hljs-keyword">this</span>.updateQueue = [];
        <span class="hljs-keyword">this</span>.isBatchUpdate = <span class="hljs-literal">false</span>;
    }
    setState = <span class="hljs-function">(<span class="hljs-params">partialState</span>) =&gt;</span> {
        <span class="hljs-keyword">this</span>.updateQueue.push(partialState);
        <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.isBatchUpdate)
            <span class="hljs-keyword">this</span>.flushState();
    }
    flushState = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">this</span>.updateQueue.reduce(<span class="hljs-function">(<span class="hljs-params">acc, cur</span>) =&gt;</span> {
            acc = { ...acc, ...cur };
            <span class="hljs-keyword">return</span> acc;
        }, <span class="hljs-keyword">this</span>.state);
        renderComponent(<span class="hljs-keyword">this</span>);
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    createElement,
    Component
}
</code></pre>
<h3 id="t408.3 react-dom\index.js">8.3 react-dom\index.js <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t408.3%20react-dom\index.js"> # </a></h3>
<p>src\react-dom\index.js</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
ReactDOM.render(element, document.getElementById('root'));
element是要渲染的元素 parent是真实的DOM元素
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>(<span class="hljs-params">element, parent, componentInstance</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> element === <span class="hljs-string">'string'</span> || <span class="hljs-keyword">typeof</span> element === <span class="hljs-string">'number'</span>) {
        <span class="hljs-keyword">return</span> parent.appendChild(<span class="hljs-built_in">document</span>.createTextNode(element));
    }
    <span class="hljs-keyword">let</span> type = element.type, props = element.props;
    <span class="hljs-keyword">let</span> isReactComponent = type.isReactComponent;
    <span class="hljs-keyword">if</span> (isReactComponent) {
        componentInstance = <span class="hljs-keyword">new</span> type(props);
        element = componentInstance.render();
        type = element.type;
        props = element.props;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> type === <span class="hljs-string">'function'</span>) {
        element = type(props);
        type = element.type;
        props = element.props;
    }
    <span class="hljs-keyword">let</span> dom = _render(type, props, componentInstance);
    <span class="hljs-keyword">if</span> (componentInstance &amp;&amp; isReactComponent) {
        componentInstance.dom = dom;
    }
    parent.appendChild(dom);
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SyntheticEvent</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-keyword">this</span>.events = {};
    }
    on = <span class="hljs-function">(<span class="hljs-params">type, dom, handler, componentInstance</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.events[type]) {
            <span class="hljs-keyword">this</span>.events[type].push({ dom, handler, componentInstance });
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">this</span>.events[type] = [{ dom, handler, componentInstance }];
        }
    }
    emit = <span class="hljs-function">(<span class="hljs-params">type, event</span>) =&gt;</span> {
        <span class="hljs-keyword">let</span> listeners = <span class="hljs-keyword">this</span>.events[type];
        listeners &amp;&amp; listeners.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
            <span class="hljs-keyword">if</span> (event.target === item.dom) {
                <span class="hljs-keyword">if</span> (item.componentInstance) {
                    item.componentInstance.isBatchUpdate = <span class="hljs-literal">true</span>;
                }
                item.handler(event);
                <span class="hljs-keyword">if</span> (item.componentInstance) {
                    item.componentInstance.isBatchUpdate = <span class="hljs-literal">false</span>;
                    item.componentInstance.flushState();
                }
            }
        });

    }
}
<span class="hljs-keyword">let</span> syntheticEvent = <span class="hljs-keyword">new</span> SyntheticEvent();
<span class="hljs-built_in">document</span>.onclick = syntheticEvent.emit.bind(<span class="hljs-literal">null</span>, <span class="hljs-string">'onclick'</span>);
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_render</span>(<span class="hljs-params">type, props, componentInstance</span>) </span>{
    <span class="hljs-keyword">let</span> dom = <span class="hljs-built_in">document</span>.createElement(type);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> propName <span class="hljs-keyword">in</span> props) {
        <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'children'</span>) {
            <span class="hljs-keyword">let</span> children = props.children;
            children.forEach(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> render(child, dom, componentInstance));
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'style'</span>) {
            <span class="hljs-keyword">let</span> styleObj = props.style;
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> attr <span class="hljs-keyword">in</span> styleObj)
                dom.style[attr] = styleObj[attr];
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (propName === <span class="hljs-string">'className'</span>) {
            dom.className = props.className
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (propName.startsWith(<span class="hljs-string">'on'</span>)) {
            <span class="hljs-comment">//currentDOM[propName.toLowerCase()] = props[propName];</span>
            syntheticEvent.on(propName.toLowerCase(), dom, props[propName], componentInstance);
        } <span class="hljs-keyword">else</span> {
            dom.setAttribute(propName, props[propName]);
        }
    }
    <span class="hljs-keyword">return</span> dom;
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    render
}
</code></pre>
<h2 id="t418.生命周期">8.生命周期 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t418.%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"> # </a></h2>
<h3 id="t428.1 旧版生命周期">8.1 旧版生命周期 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t428.1%20%E6%97%A7%E7%89%88%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"> # </a></h3>
<p><img src="./react基础_files/react15.jpg" alt="react15"></p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props { }
interface State { <span class="hljs-attr">number</span>: number }
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{ <span class="hljs-comment">// 他会比较两个状态相等就不会刷新视图 PureComponent是浅比较</span>
    <span class="hljs-keyword">static</span> defaultProps = {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'珠峰架构'</span>
    };
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">number</span>: <span class="hljs-number">0</span> }
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'1.constructor构造函数'</span>)
    }
    componentWillMount() { <span class="hljs-comment">// 取本地的数据 同步的方式：采用渲染之前获取数据，只渲染一次</span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'2.组件将要加载 componentWillMount'</span>);
    }
    componentDidMount() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'4.组件挂载完成 componentDidMount'</span>);
    }
    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.setState({ <span class="hljs-attr">number</span>: <span class="hljs-keyword">this</span>.state.number + <span class="hljs-number">1</span> });
    };
    <span class="hljs-comment">// react可以shouldComponentUpdate方法中优化 PureComponent 可以帮我们做这件事</span>
    shouldComponentUpdate(nextProps, nextState): boolean { <span class="hljs-comment">// 代表的是下一次的属性 和 下一次的状态</span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'5.组件是否更新 shouldComponentUpdate'</span>);
        <span class="hljs-keyword">return</span> nextState.number % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>;
        <span class="hljs-comment">// return nextState.number!==this.state.number; //如果此函数种返回了false 就不会调用render方法了</span>
    } <span class="hljs-comment">//不要随便用setState 可能会死循环</span>
    componentWillUpdate() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'6.组件将要更新 componentWillUpdate'</span>);
    }
    componentDidUpdate() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'7.组件完成更新 componentDidUpdate'</span>);
    }
    render() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'3.render'</span>);
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.state.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                {this.state.number &gt; 3 ? null : <span class="hljs-tag">&lt;<span class="hljs-name">ChildCounter</span> <span class="hljs-attr">n</span>=<span class="hljs-string">{this.state.number}</span> /&gt;</span>}
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        )
    }
}
class ChildCounter extends Component<span class="hljs-tag">&lt;<span class="hljs-name">{</span> <span class="hljs-attr">n:</span> <span class="hljs-attr">number</span> }&gt;</span> {
    componentWillUnmount() {
        console.log('组件将要卸载componentWillUnmount')
    }
    componentWillMount() {
        console.log('child componentWillMount')
    }
    render() {
        console.log('child-render')
        return (<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            {this.props.n}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>)
    }
    componentDidMount() {
        console.log('child componentDidMount')
    }
    componentWillReceiveProps(newProps) { // 第一次不会执行，之后属性更新时才会执行
        console.log('child componentWillReceiveProps')
    }
    shouldComponentUpdate(nextProps, nextState) {
        return nextProps.n % 3 == 0; //子组件判断接收的属性 是否满足更新条件 为true则更新
    }
}
ReactDOM.render(<span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> /&gt;</span>, document.getElementById('root'));
// defaultProps
// constructor
// componentWillMount
// render
// componentDidMount
// 状态更新会触发的
// shouldComponentUpdate nextProps,nextState=&gt;boolean
// componentWillUpdate
// componentDidUpdate
// 属性更新
// componentWillReceiveProps newProps
// 卸载
// componentWillUnmount
</span></code></pre>
<h3 id="t438.2 新版生命周期">8.2 新版生命周期 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t438.2%20%E6%96%B0%E7%89%88%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"> # </a></h3>
<p><img src="./react基础_files/react16.jpg" alt="react16"></p>
<h4 id="t448.2.1 getDerivedStateFromProps">8.2.1 getDerivedStateFromProps <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t448.2.1%20getDerivedStateFromProps"> # </a></h4>
<ul>
<li>static getDerivedStateFromProps(props, state) 这个生命周期的功能实际上就是将传入的props映射到state上面</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props { }
interface State { <span class="hljs-attr">number</span>: number }
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    <span class="hljs-keyword">static</span> defaultProps = {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'珠峰架构'</span>
    };
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">number</span>: <span class="hljs-number">0</span> }
    }

    handleClick = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.setState({ <span class="hljs-attr">number</span>: <span class="hljs-keyword">this</span>.state.number + <span class="hljs-number">1</span> });
    };

    render() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'3.render'</span>);
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.state.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">ChildCounter</span> <span class="hljs-attr">number</span>=<span class="hljs-string">{this.state.number}</span> /&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        )
    }
}
class ChildCounter extends React.Component<span class="hljs-tag">&lt;<span class="hljs-name">{</span> <span class="hljs-attr">number:</span> <span class="hljs-attr">number</span> }, { <span class="hljs-attr">number:</span> <span class="hljs-attr">number</span> }&gt;</span> {
    constructor(props) {
        super(props);
        this.state = { number: 0 };
    }
    static getDerivedStateFromProps(nextProps, prevState) {
        const { number } = nextProps;
        // 当传入的type发生变化的时候，更新state
        if (number % 2 == 0) {
            return { number: number * 2 };
        } else {
            return { number: number * 3 };
        }
        // 否则，对于state不进行任何操作
        return null;
    }
    render() {
        console.log('child-render', this.state)
        return (<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            {this.state.number}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>)
    }

}

ReactDOM.render(
    <span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h4 id="t458.2.2 getSnapshotBeforeUpdate">8.2.2 getSnapshotBeforeUpdate <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t458.2.2%20getSnapshotBeforeUpdate"> # </a></h4>
<ul>
<li>getSnapshotBeforeUpdate() 被调用于render之后，可以读取但无法使用DOM的时候。它使您的组件可以在可能更改之前从DOM捕获一些信息（例如滚动位置）。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
interface Props { }
interface State { <span class="hljs-attr">messages</span>: <span class="hljs-built_in">Array</span>&lt;string&gt; }
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ScrollingList</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>&lt;<span class="hljs-title">Props</span>, <span class="hljs-title">State</span>&gt; </span>{
    wrapper
    timeID
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">messages</span>: [] }
        <span class="hljs-keyword">this</span>.wrapper = React.createRef();
    }

    addMessage() {
        <span class="hljs-keyword">this</span>.setState(<span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> ({
            <span class="hljs-attr">messages</span>: [<span class="hljs-string">`<span class="hljs-subst">${state.messages.length}</span>`</span>, ...state.messages],
        }))
    }
    componentDidMount() {
        <span class="hljs-keyword">this</span>.timeID = <span class="hljs-built_in">window</span>.setInterval(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {<span class="hljs-comment">//设置定时器</span>
            <span class="hljs-keyword">this</span>.addMessage();
        }, <span class="hljs-number">1000</span>)
    }
    componentWillUnmount() {<span class="hljs-comment">//清除定时器</span>
        <span class="hljs-built_in">window</span>.clearInterval(<span class="hljs-keyword">this</span>.timeID);
    }
    getSnapshotBeforeUpdate() {<span class="hljs-comment">//很关键的，我们获取当前rootNode的scrollHeight，传到componentDidUpdate 的参数perScrollHeight</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.wrapper.current.scrollHeight;
    }
    componentDidUpdate(pervProps, pervState, prevScrollHeight) {
        <span class="hljs-keyword">const</span> curScrollTop = <span class="hljs-keyword">this</span>.wrapper.current.scrollTop;<span class="hljs-comment">//当前向上卷去的高度</span>
        <span class="hljs-comment">//当前向上卷去的高度加上增加的内容高度</span>
        <span class="hljs-keyword">this</span>.wrapper.current.scrollTop = curScrollTop + (<span class="hljs-keyword">this</span>.wrapper.current.scrollHeight - prevScrollHeight);
    }
    render() {
        <span class="hljs-keyword">let</span> style = {
            <span class="hljs-attr">height</span>: <span class="hljs-string">'100px'</span>,
            <span class="hljs-attr">width</span>: <span class="hljs-string">'200px'</span>,
            <span class="hljs-attr">border</span>: <span class="hljs-string">'1px solid red'</span>,
            <span class="hljs-attr">overflow</span>: <span class="hljs-string">'auto'</span>
        }
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{style}</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{this.wrapper}</span> &gt;</span>
                {this.state.messages.map((message, index) =&gt; (
                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>{message} <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                ))}
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        );
    }
}

ReactDOM.render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ScrollingList</span> /&gt;</span>,
    document.getElementById('root')
);
</span></code></pre>
<h2 id="t46参考">参考 <a href="http://www.zhufengpeixun.cn/2020/html/82.1.react.html#t46%E5%8F%82%E8%80%83"> # </a></h2>
<ul>
<li><a href="https://zh-hans.reactjs.org/">react文档</a></li>
<li><a href="https://github.com/zhufengnodejs/react">react源码</a></li>
</ul>

        <div class="copyright">Powered by <a href="https://github.com/jaywcjlove/idoc" target="_blank">idoc</a>. Dependence <a href="https://nodejs.org/">Node.js</a> run.</div>
    </div>
    
</div>

<script src="./react基础_files/jquery.js"></script>
<script>
$('.warpper .page-toc ul ul li a').on('click',function(){
  $('.warpper .page-toc ul ul li a').removeClass('my-active')
  $(this).addClass('my-active')
})

$('.logo').on('mouseenter',function(){
  $('.nav').height('450px');
})
$('.nav').on('mouseleave',function(){
  $('.nav').height('80px');
})
$('.logo').on('click',function(){
  $('.nav').css('display','none');
 $('.warpper').css('padding','0px');
})
// if (!$('.understand-me').length) {
  //   var bar = $(window).height() - $('.navbar ').height() - $('.page-toc').position().top;
  //   var count = bar / 26 / 2;
  //   var barHeight = $('.page-toc').outerHeight();
  //   $('.page-toc li').eq(0).children('a').addClass('red');
  //   var arr = [];
  //   $("h1,h2,h3,h4,h5,h6").each(function () {
  //     arr.push($(this).position().top);
  //   });
  //   var timer
  //   function dark() {
  //     clearTimeout(timer)
  //      timer = setTimeout(function () {
  //      var top = Math.abs($('.page-toc > ul').position().top);
  //      var cur = $('.content').scrollTop();
  //      for (var i = arr.length; i >= 0; i--) {
  //        if (arr[i] <= cur) {
  //          break;
  //        }
  //      }
  //      if (i === -1) {
  //        i = 0;
  //      }
  //      $('.page-toc li a').removeClass('red');
  //      $('.page-toc li').eq(i).children('a').addClass('red');
  //      let height = $('.page-toc li').eq(i).position().top-$('.page-toc').height(); // 如果当前的offset出去了 回到中间可好？
  //      $('.page-toc').scrollTop(height+$('.page-toc').height()/2);
  //    },200)
  //   }

  //   $('.content').on('scroll', dark);
  // }
</script>
<style>

    /* ::-webkit-scrollbar{width:14px;}
    ::-webkit-scrollbar-track{background-color:transparent;}
    ::-webkit-scrollbar-thumb{background-color:transparent;}
    ::-webkit-scrollbar-thumb:hover {background-color:transparent}
    ::-webkit-scrollbar-thumb:active {background-color:transparent} */

    .page-toc > ul .red {
        background: #f3f3f3;
        z-index: 1;
        border-left: 3px solid #009a61;
        -webkit-transition: all .2s ease;
        transition: all .2s ease;
        color: #000
    }





</style>


</body></html>